package com.learn.io.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;

/**
 * @classname:
 * @Description:
 * @author: yfpu
 * @Date: 2018-12-13 14:51
 */
public class NioServer {

    public static void main(String[] args) throws IOException {
        Selector selector = Selector.open();

        ServerSocketChannel ssChannel = ServerSocketChannel.open();
        ssChannel.configureBlocking(false);
        ssChannel.register(selector, SelectionKey.OP_ACCEPT);

        ServerSocket serverSocket = ssChannel.socket();
        InetSocketAddress address = new InetSocketAddress("127.0.0.1", 8888);
        serverSocket.bind(address);

        int channelCnt = 0;
        while (true) {
            int select = selector.select();

            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            Iterator<SelectionKey> keyIterator = selectionKeys.iterator();
            while (keyIterator.hasNext()) {
                SelectionKey selectionKey = keyIterator.next();

                if (selectionKey.isAcceptable()) {
                    ServerSocketChannel channel = (ServerSocketChannel) selectionKey.channel();

                    //服务器会为每个新连接创建一个SocketChannel
                    channelCnt++;
                    SocketChannel socketChannel = channel.accept();
                    socketChannel.configureBlocking(false);

                    //这个链接主要用于从客户端读取数据
                    socketChannel.register(selector, SelectionKey.OP_READ);

                } else if (selectionKey.isReadable()) {

                    SocketChannel channel = (SocketChannel) selectionKey.channel();
                    System.out.println(readDataFromSocketChannel(channel));
                    channel.close();
                    channelCnt--;
                }
            }
            System.out.println("当时连接数：" + channelCnt);
            keyIterator.remove();
        }

    }

    private static String readDataFromSocketChannel(SocketChannel channel) throws IOException {

        ByteBuffer buffer = ByteBuffer.allocate(1024);
        StringBuilder stringBuilder = new StringBuilder();
        while (true) {
            buffer.clear();

            int n = channel.read(buffer);
            if (n == -1)
                break;

            buffer.flip();
            int limit = buffer.limit();
            char[] dst = new char[limit];
            for (int i = 0; i < limit; i++) {
                dst[i] = (char) buffer.get(i);
            }

            stringBuilder.append(dst);
            buffer.clear();
        }

        return stringBuilder.toString();
    }
}
